using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Web;

namespace ASPNETLibrary.WebParts.Configuration
{
    public class XmlConfigProvider : IConfigProvider
    {
        #region [Private members]
        private Dictionary<string, WebPartTheme> _themes;
        #endregion [Private members]

        #region [Constructors]
        /// <summary>
        /// Default constructor
        /// </summary>
        public XmlConfigProvider(string xmlConfigFilePath)
        {
            this._themes = new Dictionary<string, WebPartTheme>();

            this.LoadThemes(xmlConfigFilePath);
        }

        #endregion [Constructors]

        #region IConfigProvider Members

        /// <summary>
        /// This method gets a theme with the 
        /// specified name
        /// </summary>
        /// <param name="themeName">Name of a theme to be found</param>
        /// <returns>Returns a found theme
        /// or null if theme was not found.</returns>
        public WebPartTheme GetTheme(string themeName)
        {
            WebPartTheme retVal = null;

            if (!this._themes.TryGetValue(themeName, out retVal))
            {
                retVal = null;
            }
            return retVal;
        }

        /// <summary>
        /// This method will return all themes
        /// </summary>
        /// <returns>Returns an array of themes or null
        /// if there are no themes</returns>
        public WebPartTheme[] GetAllThemes()
        {
            WebPartTheme[] retVal = null;

            if (this._themes.Count > 0)
            {
                retVal = new WebPartTheme[this._themes.Count];
                this._themes.Values.CopyTo(retVal, 0);
            }
            return retVal;
        }

        /// <summary>
        /// This method will return all skins for specified
        /// theme
        /// </summary>
        /// <param name="themeName">Name of a theme whose
        /// skins should be returned</param>
        /// <returns>Returns an array of found skins or null if 
        /// there are no skins for the theme with specified name
        /// </returns>
        public WebPartSkin[] GetSkins(string themeName)
        {
            WebPartSkin[] retVal = null;

            WebPartTheme theme = this.GetTheme(themeName);
            if (theme != null)
            {
                retVal = theme.Skins;
            }
            return retVal;
        }

        /// <summary>
        /// This method returns a skin for specified
        /// theme with the specified name
        /// </summary>
        /// <param name="themeName">Name of a theme where skin should
        /// be located</param>
        /// <param name="skinName">Name of a skin to search for</param>
        /// <returns>Returns found skin or null
        /// if skin was not found</returns>
        public WebPartSkin GetSkin(string themeName, string skinName)
        {
            WebPartSkin retVal = null;

            WebPartTheme theme = this.GetTheme(themeName);
            if (theme != null)
            {
                retVal = theme.GetSkin(skinName);
            }

            return retVal;
        }
        #endregion

        #region [Private methods]
        private void LoadThemes(string xmlConfigFilePath)
        {
            WebPartTheme[] themes;
            XmlSerializer serializer = new XmlSerializer(typeof(WebPartTheme[]));

            string xmlFullPath = HttpContext.Current.Server.MapPath(xmlConfigFilePath);
            using (StreamReader sr = new StreamReader(xmlFullPath))
            {
                themes = (WebPartTheme[])serializer.Deserialize(sr);
                sr.Close();
            }
            if (themes != null && themes.Length > 0)
            {
                foreach (WebPartTheme theme in themes)
                {
                    this._themes.Add(theme.Name, theme);
                }
            }
        }
        #endregion [Private methods]

    }
}
